import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from scipy.optimize import curve_fit


def main():
    # 读取Excel文件
    excel_file = "数据/data_24年湖南选调笔试分数统计.xlsx"  # excel中只有一列成绩数据, 没有标题没有表头
    df = pd.read_excel(excel_file, header=None, names=["Scores"])

    # 计算均值和标准差
    mean = df["Scores"].mean()
    std_dev = df["Scores"].std()

    # 定义正态分布函数
    def normal_distribution(x, mu, sigma):
        return (1 / (sigma * np.sqrt(2 * np.pi))) * np.exp(-((x - mu) ** 2) / (2 * sigma ** 2))

    # 获取数据的直方图
    hist, bin_edges = np.histogram(df["Scores"], density=True)

    # 计算直方图中点的值
    bin_centers = (bin_edges[:-1] + bin_edges[1:]) / 2

    # 利用curve_fit进行正态分布拟合
    initial_params = [mean, std_dev]
    params, covariance = curve_fit(normal_distribution, bin_centers, hist, p0=initial_params)

    # 绘制原始成绩直方图
    plt.hist(df["Scores"], bins=30, density=True, alpha=0.6, color='g', label='Histogram')

    # 绘制正态分布拟合曲线
    xmin, xmax = plt.xlim()
    x = np.linspace(xmin, xmax, 100)
    p = normal_distribution(x, params[0], params[1])
    plt.plot(x, p, 'k', linewidth=2, label='Fitted normal distribution')

    # 找到最高点坐标
    max_point_x = x[np.argmax(p)]
    max_point_y = normal_distribution(max_point_x, params[0], params[1])

    # 在图上标注最高点坐标
    plt.scatter([max_point_x], [max_point_y], color='red', marker='*', s=100, label='Max Point')

    # 在图上显示最高点坐标的具体值
    plt.text(max_point_x, max_point_y, f'({max_point_x:.2f}, {max_point_y:.2f})', color='red', fontsize=10, ha='left',
             va='bottom')

    # 显示图例和标题
    plt.title("Normal Distribution Fit for Exam Scores")
    plt.legend()

    # 显示图形
    plt.show()


if __name__ == '__main__':
    main()
